# -*- coding: utf-8 -*-
# 如果你的程序（包括注释）中包含中文，请加上上面这一行，用于指明编码（utf-8）。
# #号开头的行都是注释。

# 如何编辑本程序：
#     用任何文本编辑器均可编辑。

# 如何运行本程序：
#     在终端中，运行：python p902_2d.py
#
# 依赖模块：
#     matplotlib  (pip install matplotlib)
#     numpy       (pip install numpy)
#

# 一般的绘图只需调用pyplot子模块。
import matplotlib.pyplot as plt
import numpy as np


# 设置绘图模块的参数使之能正确显示中文（标题、图例中的中文）
plt.rcParams['font.sans-serif'] = ['FangSong']
plt.rcParams['axes.unicode_minus'] = False

#--------------------------------------------------------------
# 饼图

# 数据（比例）
data = [0.16881, 0.14966, 0.07471, 0.06992, 0.04762, 0.03541, 0.02925, 0.02411, 0.02316, 0.01409, 0.36326]
# 标签
labels = ['java', 'c', 'c++', 'python', 'visual basic', 'c#', 'php', 'javascript', 'sql', 'assembly language', '其它']
# 将排在第4位的元素（python）分离出来
explode = [0,0,0,0.3,0,0,0,0,0,0,0]
# 使用自定义颜色
colors = ['red', 'pink', 'magenta', 'purple', 'orange']
# 将横、纵坐标轴作标准化处理，保证饼图是一个正圆，否则为椭圆
plt.axes(aspect='equal')
# 控制X轴和Y轴的范围（用于控制饼图的圆心和半径）
plt.xlim(0,8)
plt.ylim(0,8)

# 绘制饼图
plt.pie(x=data, # 绘图数据
    labels=labels, # 标签
    explode=explode, # 突出显示python
    colors=colors, # 设置饼图的自定义填充色
    autopct='%.3f%%', # 设置百分比的格式，保留3位小数
    pctdistance=0.8, # 设置百分比标签与圆心的距离
    labeldistance=1.15, # 设置标签与圆心的距离
    startangle=180, # 设置饼图的初始角度
    center=(4,4), # 设置饼图的圆心
    radius=3.8, # 设置饼图的半径
    counterclock=False, # 是否为逆时针方向
    wedgeprops={'linewidth':1, 'edgecolor':'green'}, # 设置饼图内外边界的属性值
    textprops={'fontsize':12, 'color':'black'}, # 设置文本标签的属性值
    frame=1) # 是否显示饼图的框
    
# 不显示X轴和Y轴的刻度值
plt.xticks([])
plt.yticks([])
# 添加图形标题
plt.title('2018年8月的编程语言指数排行榜')
plt.show()


#--------------------------------------------------------------
# 柱状图

# 构建数据
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500, 58300, 56800, 59500, 62700]
# 绘图
plt.bar(x=x_data, height=y_data, label='Java图书销量', color='red', alpha=0.8)
plt.bar(x=x_data, height=y_data2, label='Python图书B销量', color='blue', alpha=0.8)
# 在柱状图上显示具体的数值，ha参数控制水平对齐方式，va参数控制垂直对齐方式。
# 本例中，X轴数据是字符串列表，因此X轴实际上是以列表元素的索引作为刻度值的。
# enumerate()函数每次返回一对值：索引和索引所对应的元素值。
for x,y in enumerate(y_data):
    plt.text(x, y+1000, '%s' % y, ha='center', va='bottom')
for x,y in enumerate(y_data2):
    plt.text(x, y-1000, '%s' % y, ha='center', va='top')

plt.title('Java与Python图书销量对比')
plt.xlabel('年份')
plt.ylabel('销量')
plt.legend()  # 显示图例
plt.show()

# 将条柱错开

x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500, 58300, 56800, 59500, 62700]
bar_width = 0.3
plt.bar(x=range(len(x_data)), height=y_data, label='Java图书销量', color='red', alpha=0.8, width=bar_width)
plt.bar(x=np.arange(len(x_data))+bar_width, height=y_data2, label='Python图书B销量', color='blue', alpha=0.8, width=bar_width)
# 注：np.arange()返回数组，支持数组与标量的加法（逐个相加）。
#     Python自带的range类型不支持与标量的相加。
# 注：上述bar函数把X轴刻度变成了0、1、2、3...
# 再把X轴刻度设置成原先的字符串列表：
plt.xticks(np.arange(len(x_data))+bar_width/2, x_data)

plt.title('Java与Python图书销量对比')
plt.xlabel('年份')
plt.ylabel('销量')
plt.legend()  # 显示图例
plt.show()

# 水平柱状图（条形图）

plt.barh(y=range(len(x_data)), height=bar_width, label='Java图书销量', color='red', alpha=0.8, width=y_data)
plt.barh(y=np.arange(len(x_data))+bar_width, height=bar_width, label='Python图书B销量', color='blue', alpha=0.8, width=y_data2)
plt.yticks(np.arange(len(x_data))+bar_width/2, x_data)
plt.ylabel('年份')
plt.xlabel('销量')
plt.show()


#--------------------------------------------------------------
# 散点图

# 定义从-pi到pi之间的数据，取64个数据点
x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True)

# 沿着正弦曲线绘制散点图
plt.scatter(x_data, np.sin(x_data), # 设置X和Y
    c='purple', # 设置点的颜色
    s=50, # 设置点的半径
    alpha=0.5, # 设置透明度
    marker='p', # 设置使用五边形标记
    linewidths=1, # 设置边框的线宽
    edgecolors=['green', 'yellow']) # 设置边框的颜色
# 查看所有可用标记：
#  import matplotlib
#  print(matplotlib.markers.MarkerStyle.markers)
    
# 绘制第二个散点图（只包含起点），以突出起点
plt.scatter(x_data[0], np.sin(x_data[0]), c='red', s=150, alpha=1)
# 绘制第三个散点图（只包含结束点），以突出结束点
plt.scatter(x_data[63], np.sin(x_data[63]), c='black', s=150, alpha=1)

plt.gca().spines['right'].set_color('none')  # 不显示右边框
plt.gca().spines['top'].set_color('none')  # 不显示上边框
plt.gca().spines['bottom'].set_position(('data', 0))  # 将X轴移到y=0处
plt.gca().spines['left'].set_position(('data', 0))  # 将Y轴移到x=0处

plt.title('正弦曲线的散点图')
plt.show()

